/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Codec
 * @{
 *
 * @brief Codec模块接口定义。
 *
 * Codec模块涉及自定义类型、音视频编解码组件初始化、参数设置、数据的轮转和控制等。
 *
 * @since 3.1
 * @version 2.0
 */

/**
 * @file codec_component_if.h
 *
 * @brief 主要包括Codec组件接口定义。
 *
 * Codec模块提供了获取组件信息、给组件发送命令、组件参数设置、buffer轮转和控制等接口定义。创建组件后，可使用下列接口进行编解码处理。
 *
 * @since 3.1
 * @version 2.0
 */

#ifndef CODEC_COMPONENT_IF_H
#define CODEC_COMPONENT_IF_H

#include "codec_callback_if.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @brief Codec组件接口定义。
 *
 * 主要提供以下功能:
 * - 获取组件的版本
 * - 组件参数配置的获取和设置
 * - 发送命令至组件及获取组件状态
 * - 设置回调函数
 * - 设置/释放组件使用的buffer
 * - 编解码输入输出buffer处理
 * 具体方法使用详见函数说明。
 */
struct CodecComponentType {
    /**
     * @brief 获取Codec组件版本号。
     *
     * 通过查询组件，返回组件版本信息。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param verInfo 输出参数，指向组件版本信息的指针，详见{@link CompVerInfo}。
     *
     * @return HDF_SUCCESS 表示获取版本号成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，获取版本号失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，获取版本号失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，获取版本号失败。
     *
     * @since 3.1
     */
    int32_t (*GetComponentVersion)(struct CodecComponentType *self, struct CompVerInfo *verInfo);

    /**
     * @brief 发送命令给组件。
     *
     * 发送命令给组件，当命令为设置状态时，会有事件回调通知结果给上层，其他命令则没有事件上报。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param cmd 输入参数，组件要执行的命令，详见{@link OMX_COMMANDTYPE}。
     * @param param 输入参数，组件要执行的命令携带的参数。
     * - 当cmd为OMX_CommandStateSet时，param的值详见{@link OMX_STATETYPE}。
     * - 当cmd为OMX_CommandFlush、OMX_CommandPortDisable、OMX_CommandPortEnable、OMX_CommandMarkBuffer时，param为目标端口。
     * @param cmdData 输入参数，当cmd为OMX_CommandMarkBuffer时，指向OMX_MARKTYPE结构体指针。
     * @param cmdDataLen 输入参数，上层传递的cmdData字节数。
     *
     * @return HDF_SUCCESS 表示发送命令成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，发送命令失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，发送命令失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，发送命令失败。
     *
     * @since 3.1
     */
    int32_t (*SendCommand)(struct CodecComponentType *self, enum OMX_COMMANDTYPE cmd, uint32_t param,
        int8_t *cmdData, uint32_t cmdDataLen);

    /**
     * @brief 获取组件参数设置。
     *
     * 当组件处于除了OMX_StateInvalid（组件状态异常）之外的其他状态，用户可通过此接口获取组件参数。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param paramIndex 输入参数，待填充结构的索引，详见{@link OMX_INDEXTYPE}。
     * @param paramStruct 输入输出参数，指向由组件填充的应用程序分配的结构体指针。
     * @param paramStructLen 输入参数，paramStruct字节数。
     *
     * @return HDF_SUCCESS 表示获取参数成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，获取参数失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，获取参数失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，获取参数失败。
     *
     * @since 3.1
     */
    int32_t (*GetParameter)(struct CodecComponentType *self, uint32_t paramIndex, int8_t *paramStruct,
        uint32_t paramStructLen);

    /**
     * @brief 设置组件需要的参数。
     *
     * 当组件处于OMX_StateLoaded、OMX_StateWaitForResources状态或者端口是去使能状态，用户可通过此接口设置组件参数。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param index 输入参数，要设置的结构索引，详见{@link OMX_INDEXTYPE}。
     * @param paramStruct 输入参数，指向组件用于初始化的应用程序分配结构的指针。
     * @param paramStructLen 输入参数，paramStruct字节数。
     *
     * @return HDF_SUCCESS 表示设置参数成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，设置参数失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，设置参数失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，设置参数失败。
     *
     * @since 3.1
     */
    int32_t (*SetParameter)(struct CodecComponentType *self, uint32_t index, int8_t *paramStruct,
        uint32_t paramStructLen);

    /**
     * @brief 获取组件的配置结构。
     *
     * 加载组件后可以随时调用此接口获取组件的配置。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param index 输入参数，待填充结构的索引，详见{@link OMX_INDEXTYPE}。
     * @param cfgStruct 输入输出参数，指向由组件填充的应用程序分配的结构体指针。
     * @param cfgStructLen 输入参数，上层传入的cfgStruct字节数。
     *
     * @return HDF_SUCCESS 表示获取配置成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，获取配置失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，获取配置失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，获取配置失败。
     *
     * @since 3.1
     */
    int32_t (*GetConfig)(struct CodecComponentType *self, uint32_t index, int8_t *cfgStruct, uint32_t cfgStructLen);

    /**
     * @brief 设置组件的配置。
     *
     * 加载组件后可以随时调用此接口设置组件的配置。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param index 输入参数，要设置的结构索引，详见{@link OMX_INDEXTYPE}。
     * @param cfgStruct 输入参数，指向组件用于初始化的应用程序分配结构的指针。
     * @param cfgStructLen 输入参数，cfgStruct字节数。
     *
     * @return HDF_SUCCESS 表示设置配置成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，设置失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，设置失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，设置失败。
     *
     * @since 3.1
     */
    int32_t (*SetConfig)(struct CodecComponentType *self, uint32_t index, int8_t *cfgStruct, uint32_t cfgStructLen);

    /**
     * @brief 根据字符串获取组件的扩展索引。
     *
     * 将扩展字符串转换为Openmax IL结构索引。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param paramName 输入参数，组件用来转换为配置索引的字符串。
     * @param indexType 输出参数，由paramName转换的配置索引，详见{@link OMX_INDEXTYPE}。
     *
     * @return HDF_SUCCESS 表示获取扩展索引成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，获取扩展索引失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，获取扩展索引失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，获取扩展索引失败。
     *
     * @since 3.1
     */
    int32_t (*GetExtensionIndex)(struct CodecComponentType *self, const char *paramName, uint32_t *indexType);

    /**
     * @brief 获取组件的当前状态。
     *
     * 用户可调用此接口获取组件的当前状态，组件状态详见{@link OMX_STATETYPE}。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param state 输出参数，指向获取到的状态指针，组件状态详见{@link OMX_STATETYPE}。
     *
     * @return HDF_SUCCESS 表示获取状态成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，获取状态失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，获取状态失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，获取状态失败。
     *
     * @since 3.1
     */
    int32_t (*GetState)(struct CodecComponentType *self, enum OMX_STATETYPE *state);

    /**
     * @brief 设置组件采用Tunnel方式通信。
     *
     * 当组件处于OMX_StateLoaded 状态时，用户通过调用此接口确定组件是否可以进行Tunnel传输，如果可以则设置组件的Tunnel传输。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param port 输入参数，组件设置的端口。
     * @param tunneledComp 输入参数，组件的tunnel handle。
     * @param tunneledPort 输入参数，组件用来Tunnel通信的端口。
     * @param tunnelSetup 输入输出参数，指向Tunnel设置的结构体{@link OMX_TUNNELSETUPTYPE}指针。
     *
     * @return HDF_SUCCESS 表示设置成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，设置失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，设置失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，设置失败。
     *
     * @since 3.1
     */
    int32_t (*ComponentTunnelRequest)(struct CodecComponentType *self, uint32_t port,
        int32_t tunneledComp, uint32_t tunneledPort, struct OMX_TUNNELSETUPTYPE *tunnelSetup);

    /**
     * @brief 指定组件端口的buffer。
     *
     * 此接口在以下情况下使用：
     * - 当组件处于OMX_StateLoaded状态，并且用户已经向组件发送OMX_StateIdle状态转换请求。
     * - 当组件处于OMX_StateWaitForResources状态，所需的资源可用，并且组件已准备好进入OMX_StateIdle状态。
     * - 在去使能端口上，组件处于OMX_StateExecuting、OMX_StatePause或OMX_StateIdle状态。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param portIndex 输入参数，指定的组件端口。
     * @param buffer 输入输出参数，指向要使用的buffer结构体{@link OmxCodecBuffer}指针。
     *
     * @return HDF_SUCCESS 表示指定成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，指定失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，指定失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，指定失败。
     *
     * @since 3.1
     */
    int32_t (*UseBuffer)(struct CodecComponentType *self, uint32_t portIndex, struct OmxCodecBuffer *buffer);

    /**
     * @brief 向组件申请端口buffer。
     *
     * 向组件申请分配新的buffer，此接口在以下情况下使用：
     * - 当组件处于OMX_StateLoaded状态，并且用户已经向组件发送OMX_StateIdle状态转换请求。
     * - 当组件处于OMX_StateWaitForResources状态，所需的资源可用，并且组件已准备好进入OMX_StateIdle状态。
     * - 在去使能端口上，组件处于OMX_StateExecuting、OMX_StatePause或OMX_StateIdle状态。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param portIndex 输入参数，指定的组件端口。
     * @param buffer 输入输出参数，指向要申请的buffer结构体{@link OmxCodecBuffer}指针。
     *
     * @return HDF_SUCCESS 表示申请buffer成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，申请buffer失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，申请buffer失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，申请buffer失败。
     *
     * @since 3.1
     */
    int32_t (*AllocateBuffer)(struct CodecComponentType *self, uint32_t portIndex, struct OmxCodecBuffer *buffer);

    /**
     * @brief 释放buffer。
     *
     * 此接口在以下情况下使用：
     * - 当组件处于OMX_StateIdle状态，并且已经向组件发送OMX_StateLoaded状态转换请求。
     * - 在去使能端口上，组件处于OMX_StateExecuting、OMX_StatePause或OMX_StateIdle时调用。
     * - 此接口调用可随时进行，但是如果未在上述情况下执行，可能会导致组件上报OMX_ErrorPortUnpopulated事件。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param portIndex 输入参数，指定的组件端口。
     * @param buffer 输入参数，指向{@link OmxCodecBuffer}结构体的指针。
     *
     * @return HDF_SUCCESS 表示释放buffer成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，释放buffer失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，释放buffer失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，释放buffer失败。
     *
     * @since 3.1
     */
    int32_t (*FreeBuffer)(struct CodecComponentType *self, uint32_t portIndex, const struct OmxCodecBuffer *buffer);

    /**
     * @brief 编解码输入待处理buffer。
     *
     * 此接口在组件处于OMX_StateExecuting或者OMX_StatePause状态时调用。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param buffer 输入参数，指向{@link OmxCodecBuffer}结构体的指针。
     *
     * @return HDF_SUCCESS 表示输入buffer成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，输入buffer失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，输入buffer失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，输入buffer失败。
     *
     * @since 3.1
     */
    int32_t (*EmptyThisBuffer)(struct CodecComponentType *self, const struct OmxCodecBuffer *buffer);

    /**
     * @brief 编解码输出填充buffer。
     *
     * 此接口在组件处于OMX_StateExecuting或者OMX_StatePause状态时调用。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param buffer 输入参数，指向{@link OmxCodecBuffer}结构体的指针。
     *
     * @return HDF_SUCCESS 表示填充buffer成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，填充buffer失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，填充buffer失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，填充buffer失败。
     *
     * @since 3.1
     */
    int32_t (*FillThisBuffer)(struct CodecComponentType *self, const struct OmxCodecBuffer *buffer);

    /**
     * @brief 设置Codec组件的回调函数。
     *
     * 当组件处于OMX_StateLoaded状态时，使用此回调函数向上通知事件以及上报可用的输入输出信息。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param callback 输入参数，指向回调函数{@link CodecCallbackType}对象指针。
     * @param appData 输入参数，指向应用程序定义的值的指针，该值将在回调期间返回。
     * @param appDataLen 输入参数，上层传递的appData字节数。
     *
     * @return HDF_SUCCESS 表示设置回调成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，设置回调失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，设置回调失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，设置回调失败。
     *
     * @since 3.1
     */
    int32_t (*SetCallbacks)(struct CodecComponentType *self, struct CodecCallbackType *callback,
        int8_t *appData, uint32_t appDataLen);

    /**
     * @brief 组件去初始化。
     *
     * 调用此接口使组件去初始化，当组件处于OMX_StateLoaded状态时，将直接关闭组件。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     *
     * @return HDF_SUCCESS 表示去初始化成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，去初始化失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，去初始化失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，去初始化失败。
     *
     * @since 3.1
     */
    int32_t (*ComponentDeInit)(struct CodecComponentType *self);

    /**
     * @brief 使用已在EGL中申请的空间。
     *
     * 此接口在以下情况下使用：
     * - 当组件处于OMX_StateLoaded状态，并且已经向组件发送OMX_StateIdle状态转换请求。
     * - 当组件处于OMX_StateWaitForResources状态，所需的资源可用，并且组件已准备好进入OMX_StateIdle状态。
     * - 在去使能端口上，组件处于OMX_StateExecuting、OMX_StatePause或OMX_StateIdle状态。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param buffer 输入输出参数，指向{@link OmxCodecBuffer}结构体的指针。
     * @param portIndex 输入参数，指定的组件端口。
     * @param eglImage  输入参数，EGL申请的图像指针。
     * @param eglImageLen 输入参数，eglImage字节数。
     *
     * @return HDF_SUCCESS 表示使用成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，使用失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，使用失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，使用失败。
     *
     * @since 3.1
     */
    int32_t (*UseEglImage)(struct CodecComponentType *self, struct OmxCodecBuffer *buffer, uint32_t portIndex,
        int8_t *eglImage, uint32_t eglImageLen);

    /**
     * @brief 获取组件角色。
     *
     * 根据组件角色索引获取对应组件角色。
     *
     * @param self 输入参数，指向要操作的Codec组件指针。
     * @param role 输出参数，角色名称。
     * @param roleLen 输入参数，role字节数。
     * @param index 输入参数，角色的索引，一个组件可能支持多种角色。
     *
     * @return HDF_SUCCESS 表示获取角色成功。
     * @return HDF_ERR_INVALID_PARAM 表示参数无效，获取角色失败。
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效，获取角色失败。
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败，获取角色失败。
     *
     * @since 3.1
     */
    int32_t (*ComponentRoleEnum)(struct CodecComponentType *self, uint8_t *role, uint32_t roleLen, uint32_t index);
};

/**
 * @brief 实例化CodecComponentType对象。
 *
 * @param remote 输入参数，指向RemoteService的指针。
 *
 * @return 实例化的CodecComponentType对象。
 */
struct CodecComponentType *CodecComponentTypeGet(struct HdfRemoteService *remote);

/**
 * @brief 释放CodecComponentType对象。
 *
 * @param instance 输入参数，指向CodecComponentType实例的指针。
 *
 * @since 3.1
 */
void CodecComponentTypeRelease(struct CodecComponentType *instance);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif // CODEC_COMPONENT_IF_H
/** @} */
